4.3 Виджеты. Stack и Positioned
3 из 3 шагов пройдено

 Виджеты. Stack и Positioned

➡️Ссылка на репозиторий с кодом этого урока

Текст поверх Фонового Изображения

Очень частая задача - разместить текст или другие элементы поверх изображения. Stack идеально подходит для этого.

class StackExample3 extends StatelessWidget {  
  const StackExample3({super.key});  
  
  @override  
  Widget build(BuildContext context) {  
    return Center(  
      child: SizedBox(  
        // Ограничиваем размер Stack для примера  
        width: 350,  
        height: 350,  
        child: Stack(  
          children: <Widget>[  
            // Фоновое изображение (внизу Stack)  
            Image.asset(  
              'assets/images/student1.jpeg', 
              fit: BoxFit.contain, // Изображение покроет доступное пространство  
              width: double.infinity, // Растягиваем по ширине контейнера Stack  
              height: double.infinity, // Растягиваем по высоте контейнера Stack  
            ),  
            Positioned(  
              bottom: 20, // Отступ 20 от нижнего края Stack  
              left: 20, // Отступ 20 от левого края Stack  
              child: Container(  
                padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),  
                decoration: BoxDecoration(  
                  color: Colors.black.withValues(alpha: 0.7),  
                ),  
                child: Text(  
                  'Flutter курс 2025',  
                  style: TextStyle(  
                    fontSize: 24,  
                    color: Colors.white,
                    fontWeight: FontWeight.bold,  
                  ),  
                ),  
              ),  
            ),  
          ],  
        ),  
      ),  
    );  
  }  
}

Создание Виджета "Бейдж" (Badge)

Это классический пример использования Stack и Positioned для создания наложения. Бейдж — это обычно небольшой значок (например, с числом уведомлений), расположенный поверх другого элемента (например, аватара или иконки).

Очень частая задача: показать количество уведомлений рядом с аватаром или иконкой. Stack и Positioned идеально подходят для этого!

class StackExample4 extends StatelessWidget {  
  const StackExample4({super.key});  
  
  @override  
  Widget build(BuildContext context) {  
    return Center(  
      child: Card(  
        color: Colors.yellow[100],  
        margin: EdgeInsets.all(20.0),  
        elevation: 1,  
        child: Padding(  
          padding: const EdgeInsets.all(16.0),  
          child: Row(   
            mainAxisSize: MainAxisSize.min,
            children: [  
              // Контейнер Stack для аватара и бейджа  
              Stack(  
                clipBehavior: Clip.none, // Позволяет бейджу выходить за границы аватара  
                children: <Widget>[  
                  CircleAvatar(  
                    radius: 30,
                    backgroundImage: AssetImage(  
                      'assets/images/student2.png',  
                    ),
                  ),  
                  // Бейдж (позиционирован относительно аватара через Stack)  
                  Positioned(  
                    top: -5, // Сдвигаем немного вверх от верхнего края Stack (аватара)  
                    right: -5, // Сдвигаем немного вправо от правого края Stack (аватара)  
                    child: Container(  
                      padding: EdgeInsets.all(4),
                      decoration: BoxDecoration(  
                        color: Colors.red, // Красный фон бейджа  
                        shape: BoxShape.circle, // Круглая форма  
                      ),  
                      constraints: BoxConstraints(   
                        minWidth: 20,  
                        minHeight: 20,  
                      ),  
                      child: Center(  
                        child: Text(  
                          '5',
                          style: TextStyle(  
                            color: Colors.white,
                            fontSize: 12,
                            fontWeight: FontWeight.bold,  
                          ),  
                        ),  
                      ),  
                    ),  
                  ),  
                ],  
              ),  
              SizedBox(width: 16),
              Column(  
                crossAxisAlignment: CrossAxisAlignment.start,  
                mainAxisSize: MainAxisSize.min,  
                children: [  
                  Text(  
                    "Имя пользователя",  
                    style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),  
                  ),  
                  Text(  
                    "Онлайн",  
                    style: TextStyle(fontSize: 14, color: Colors.grey[600]),  
                  ),  
                ],  
              ),  
            ],  
          ),  
        ),  
      ),  
    );  
  }  
}


Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий